﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows;
using System.Windows.Documents;

namespace DiagramDesigner
{
    /// <summary>Draws a selection rectangle on an AdornerLayer.</summary>
    internal sealed class SelectionAdorner : Adorner
    {
        private Rect selectionRect;
        private double lineWidth;

        /// <summary>
        /// Initializes a new instance of the SelectionAdorner class.
        /// </summary>
        /// <param name="parent">
        /// The UIElement which this instance will overlay.
        /// </param>
        /// <exception cref="ArgumentNullException">parent is null.</exception>
        public SelectionAdorner(FrameworkElement parent)
            : base(parent)
        {
            // Make sure the mouse doesn't see us.
            this.IsHitTestVisible = false;

            // We only draw a rectangle when we're enabled.
            this.IsEnabledChanged += delegate { this.InvalidateVisual(); };

            UseLayoutRounding = true;
            SnapsToDevicePixels = true;

        }

        /// <summary>Gets or sets the area of the selection rectangle.</summary>
        public Rect SelectionArea
        {
            get
            {
                return this.selectionRect;
            }
            set
            {
                this.selectionRect = value;
                this.InvalidateVisual();
            }
        }

        public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
        {
            double scaleX = 1, scaleY = 1;

            MatrixTransform mt = transform as MatrixTransform;
            if (mt != null)
            {
                scaleX = 1.0 / Math.Sqrt(mt.Matrix.M11 * mt.Matrix.M11 + mt.Matrix.M12 * mt.Matrix.M12);
                scaleY = 1.0 / Math.Sqrt(mt.Matrix.M21 * mt.Matrix.M21 + mt.Matrix.M22 * mt.Matrix.M22);

                lineWidth = scaleX;
            }
            return base.GetDesiredTransform(transform);
        }

        /// <summary>
        /// Participates in rendering operations that are directed by the layout system.
        /// </summary>
        /// <param name="drawingContext">The drawing instructions.</param>
        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            if (this.IsEnabled)
            {

                // Make the lines snap to pixels (add half the pen width [0.5])
                double[] x = { this.SelectionArea.Left + 0.5 * lineWidth, this.SelectionArea.Right + 0.5 * lineWidth };
                double[] y = { this.SelectionArea.Top + 0.5 * lineWidth, this.SelectionArea.Bottom + 0.5 * lineWidth };
                drawingContext.PushGuidelineSet(new GuidelineSet(x, y));

                Brush fill = SystemColors.HighlightBrush.Clone();
                fill.Opacity = 0.4;
                drawingContext.DrawRectangle(fill, new Pen(SystemColors.HighlightBrush, lineWidth), this.SelectionArea);
            }
        }
    }
}

